package mathsys2;

import java.util.Objects;

/**
 * 算式类：《面向对象软件构造》1.2节+《模块化软件构造》故事二/三需求
 * 约束：加法和≤100、减法差≥0、仅支持±、加法交换律去重
 */
public class Arithmetic {
    private final int num1;
    private final int num2;
    private final char operator;
    private final int result;

    // 构造方法：校验实验约束
    public Arithmetic(int num1, int num2, char operator) {
        // 运算数范围校验（0-100，两份实验共同约束）
        if (num1 < 0 || num1 > 100 || num2 < 0 || num2 > 100) {
            throw new IllegalArgumentException("运算数必须在0-100之间（实验约束）");
        }
        // 运算符校验（仅支持±，两份实验共同约束）
        if (operator != '+' && operator != '-') {
            throw new IllegalArgumentException("仅支持 '+' 和 '-' 运算符（实验约束）");
        }
        // 加法结果校验（《模块化软件构造》故事二）
        if (operator == '+' && num1 + num2 > 100) {
            throw new IllegalArgumentException("加法结果超100：" + num1 + "+" + num2);
        }
        // 减法结果校验（《模块化软件构造》故事二）
        if (operator == '-' && num1 < num2) {
            throw new IllegalArgumentException("减法结果为负：" + num1 + "-" + num2);
        }

        this.num1 = num1;
        this.num2 = num2;
        this.operator = operator;
        this.result = calculateResult();
    }

    // 计算运算结果
    private int calculateResult() {
        return operator == '+' ? num1 + num2 : num1 - num2;
    }

    // 格式化算式（适配《面向对象软件构造》4.3节显示需求，如“3 + 5 = ?”）
    @Override
    public String toString() {
        return num1 + " " + operator + " " + num2 + " = ?";
    }

    // 去重逻辑：加法交换律、减法非交换律（《模块化软件构造》故事三）
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Arithmetic that = (Arithmetic) o;
        if (operator == '+' && that.operator == '+') {
            return (num1 == that.num1 && num2 == that.num2) || (num1 == that.num2 && num2 == that.num1);
        }
        return num1 == that.num1 && num2 == that.num2 && operator == that.operator;
    }

    // 配合equals()确保集合去重有效
    @Override
    public int hashCode() {
        return operator == '+' ?
                Objects.hash(Math.min(num1, num2), Math.max(num1, num2), operator) :
                Objects.hash(num1, num2, operator);
    }

    // Getter方法（习题类需获取属性）
    public int getNum1() { return num1; }
    public int getNum2() { return num2; }
    public char getOperator() { return operator; }
    public int getResult() { return result; }
}